<?php

namespace App\Models;

use App\Exceptions\CouponCodeUnavailableException;
use App\Service\CouponService;
use App\User;
use function foo\func;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;

class Coupon extends Model
{
    use SoftDeletes;

    protected $table = 'coupon';

    protected $typeMap = [
        1 => '满减券',
        2 => '折扣券',
    ];

    /**
     * 是否折扣券
     *
     * @return bool
     */
    public function isDiscount()
    {
        return $this->type == 2;
    }

    /**
     * 是否满减券
     *
     * @return bool
     */
    public function isReduction()
    {
        return $this->type == 1;
    }

    /**
     * 检测优惠券是否可以达到要求可以使用
     */
    public function isUse($price)
    {
        if(bccomp($price, $this->full_reduction_amount,2) == -1)
        {
            return false;
        }
        // 是否 满减券，减少优惠金额是小于0
        if ($price - $this->price < 0 && $this->type == 1) {
            return false;
        }
        return true;
    }

    // 关联优惠券领取表
    public function memberCoupon()
    {
        return $this->hasMany(MemberCoupon::class,'coupon_id', 'id');
    }

    public function getDescriptionAttribute()
    {
        $str = '';

        if ($this->full_reduction_amount > 0) {
            $str = '满'.str_replace('.00', '', $this->full_reduction_amount);
        }
        if ($this->isDiscount()) {
            return $str.'打'.str_replace('.00', '', $this->discount_rate) / 10 . '折';
        }
        if ($this->full_reduction_amount > 0) {
            return $str.'减'.str_replace('.00', '', $this->price);
        } else {
            return '无门槛';
        }
    }

    /**
     * 下单检测优惠券是否可以使用
     *
     * @param User $user
     * @param null $orderAmount
     * @throws CouponCodeUnavailableException
     */
    public function checkAvailable(User $user)
    {
        $memberCoupon = $user->coupons()->where('coupon_id', $this->id)
            ->where('use_at', null)
            ->first();
        if(is_null($memberCoupon)) {
            throw new CouponCodeUnavailableException('您未拥有该优惠券');
        }
        if ($memberCoupon->use_at <> null) {
            throw new CouponCodeUnavailableException('优惠券已使用');
        }
        $endTime =  $memberCoupon->end_time;
        if ($endTime && Carbon::parse($endTime)->lte(Carbon::now())) {
            throw new CouponCodeUnavailableException('该优惠券已过期');
        }
    }

    /**
     * 根据金额获取优惠折扣后的金额
     * @param $orderAmount
     * @return mixed|string
     */
    public function getAdjustedPrice($orderAmount)
    {
        // 满减券
        if ($this->isReduction()) {
            return bcsub($orderAmount, $this->price,2);
        }
        return bcmul($orderAmount,bcdiv($this->discount_rate,100,1),2);
    }

    /**
     * 使用优惠券
     * @param User $user
     * @param bool $increase
     * @return bool|int
     */
    public function changeUsed(User $user, $increase = true)
    {
        // 传入 true 代表新增用量，否则是减少用量
        if ($increase) {
            $res = $this->increment('used');
            if($res)
            {
                return $user->coupons()->where('coupon_id', $this->id)->update(['use_at' => now()]);
            }
            return false;
        } else {
            $couponExists = $user->coupons()->where('coupon_id', $this->id)
                ->where('use_at', null)
                ->where('end_time', '>', now())->exists();
            if (!$couponExists) {
                $user->coupons()->where('coupon_id', $this->id)->update(['use_at' => null]);
                return $this->decrement('used');
            }
        }
    }

    /**
     * 检测优惠券是否可以领取
     *
     * @throws CouponCodeUnavailableException
     */
    public function checkReceiveCoupon()
    {
        // 时间
        if ($this->end_time != null && Carbon::parse($this->end_time)->lt(now())) {
            throw new CouponCodeUnavailableException('该优惠券兑换时间已经过');
        }
        // 获取 已经领取的数量
        $count = $this->memberCoupon()->count();
        if ($this->send_count != -1 &&  $count >= $this->send_count) {
            throw new CouponCodeUnavailableException('该优惠券已被兑完');
        }
    }

    //检测商品是否可以用该优惠券
    public function checkProductIsUse($product_id)
    {
        if (!empty($this->product_id)) {
            return collect(explode(',', $this->product_id))->some(function ($item) use ($product_id){
                return in_array($item, $product_id);
            });
        }
        return true;
    }

    // 格式化时间
    public function getTimeAttribute()
    {
        $time = app(CouponService::class)->computedExporedTime($this);
        $time['start_time'] = Carbon::parse($time['start_time'])->format('Y.m.d');
        $time['end_time'] = Carbon::parse($time['end_time'])->format('Y.m.d');
        return implode('-', $time);
    }

    public function getPriceAttribute($value)
    {
        return floatval($value);
    }

    public function product()
    {
        return $this->hasOneThrough(Product::class,ProductCouponMiddles::class,'coupon_id','id','id','product_id');
    }

    public function getFullReductionAmountAttribute($value)
    {
        return floatval($value);
    }

    public function getTypeNameAttribute()
    {
        return $this->typeMap[$this->type];
    }

    // 是否领取优惠券
    public function getIsReceiveAttribute()
    {
        $user = auth('api')->user();
        if ($user) {
            return $this->memberCoupon()
                ->where('use_at', null)
                ->where('end_time', '>', now())
                ->where('user_id',  $user->id)->exists();
        }
        return false;
    }

    // 获取优惠券的商品名称
    public function getProductNameAttribute()
    {
        if ($this->product()->exists()) {
            return $this->product()->select('product_id', 'title')->first();
        }
        return '';
    }
}
